package observer

import (
	"fmt"
	"sync"
)

// 以订单为例演示观察者模式

// 主题接口
type OrderSubject interface {
	RegisterObserver(observer OrderObserver)
	RemoveObserver(observer OrderObserver)
	NotifyObservers()
}

// 观察者接口
type OrderObserver interface {
	Update(orderId string, status string)
}

// 具体主题 - 订单
type Order struct {
	observers []OrderObserver
	mu        sync.Mutex
	ID        string
	Status    string
}

func NewOrder(id string) *Order {
	return &Order{
		ID:     id,
		Status: "created",
	}
}

func (o *Order) RegisterObserver(observer OrderObserver) {
	o.mu.Lock()
	defer o.mu.Unlock()
	o.observers = append(o.observers, observer)
}
func (o *Order) RemoveObserver(observer OrderObserver) {
	o.mu.Lock()
	defer o.mu.Unlock()
	for i, obs := range o.observers {
		if obs == observer {
			o.observers = append(o.observers[:i], o.observers[i+1:]...)
			break
		}
	}
}
func (o *Order) NotifyObservers() {
	o.mu.Lock()
	observers := make([]OrderObserver, len(o.observers))
	copy(observers, o.observers)
	defer o.mu.Unlock()
	// 异步通知 - 避免阻塞流程
	go func(orderId, status string) {
		for _, observer := range observers {
			observer.Update(orderId, status)
		}
	}(o.ID, o.Status)
}
func (o *Order) UpdateStatus(status string) {
	o.Status = status
	fmt.Printf("订单[%s]状态更新: %s\n", o.ID, o.Status)
	o.NotifyObservers()
}

// 具体观察者实现
// 库存管理系统
type InventorySystem struct {
	name string
}

func (i *InventorySystem) Update(orderId string, status string) {
	switch status {
	case "paid":
		fmt.Printf("[%s] 释放库存锁定: 订单%s\n", i.name, orderId)
	case "canceled":
		fmt.Printf("[%s] 恢复库存: 订单%s\n", i.name, orderId)
	}
}

// 物流系统
type LogisticsSystem struct {
}

func (l *LogisticsSystem) Update(orderId string, status string) {
	message := map[string]string{
		"paid":     "您的订单已支付成功",
		"shipped":  "商品已发货",
		"canceled": "订单已取消",
	}[status]

	if message != "" {
		fmt.Printf("[通知] 发送给用户: %s (订单%s)\n", message, orderId)
	}
}
